package com.rs.processor;

import cn.hutool.json.JSONUtil;
import com.rs.entity.basic.*;
import com.rs.util.CalcMapUtil;
import com.rs.util.CoordinatorNodeUtil;
import com.rs.util.NodeUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TreeSet;

/**
 * 地图初始化处理器
 *
 * @author zhouwz
 * @date 2020/9/14 21:16
 */
@Slf4j
@Component
public class MapInitProcessor {

    /**
     * 点位信息处理
     *
     * @param mapInfo   地图对象
     * @param pointList 所有点位信息
     */
    public void pointHandler(MapInfo mapInfo, List<MapDataPointVO> pointList) {
        if (pointList.size() == 0) {
            log.error("[初始化地图] 点位信息为空!");
            return;
        }
        TreeSet<BigDecimal> x = new TreeSet<>();
        TreeSet<BigDecimal> y = new TreeSet<>();
        for (MapDataPointVO point : pointList) {
            x.add(point.getXCoordinate());
            y.add(point.getYCoordinate());
            // 点信息分析(content中的对象解析)
            contentAnalyse(point);
            // 点位字典准备(别名:点位)(x,y:点位)
            NodeUtil.put(point);
            // 点位编号字典
            NodeUtil.putPointCodeMap(point);
            CoordinatorNodeUtil.put(point);
        }
        // 初始化地图最大小值
        mapInfo.setMapDataExtremum(new MapDataExtremumVO(x.last(), x.first(), y.last(), y.first()));
        // 初始化地图点位信息
        mapInfo.setMapDataPointList(pointList);
    }

    /**
     * 线信息处理
     *
     * @param mapInfo   地图对象
     * @param lineList  所有线信息
     * @param pointList 所有点位信息
     */
    public void lineHandler(MapInfo mapInfo, List<MapDataLineVO> lineList, List<MapDataPointVO> pointList) {
        // 等循环线的时候获取坐标值
        Map<String, MapDataPointVO> pointRcsMap = new HashMap<>(512);
        pointList.forEach(point -> pointRcsMap.put(point.getMainKey(), point));

        // 计算角度和距离
        for (MapDataLineVO element : lineList) {
            String fromPoint = element.getFromPoint();
            String toPoint = element.getToPoint();
            if (fromPoint != null && toPoint != null) {
                if (pointRcsMap.containsKey(fromPoint) && pointRcsMap.containsKey(toPoint)) {
                    element.setAngle(BigDecimal.valueOf(CalcMapUtil.getAngel(pointRcsMap.get(fromPoint), pointRcsMap.get(toPoint))));
                    element.setWidth(String.valueOf(CalcMapUtil.getDistance(pointRcsMap.get(fromPoint), pointRcsMap.get(toPoint))));
                }
            }
            // 删除"maxSpeed".equals(vo.getMark())内容设置,模拟器应该用不到
        }
        mapInfo.setMapDataLineList(lineList);
    }

    /**
     * 点信息分析(content中的对象解析)
     *
     * @param point 点对象
     */
    private void contentAnalyse(MapDataPointVO point) {
        Object content = point.getContent();
        if (content != null && !content.toString().isEmpty()) {
            List<MapContentInfo> list = JSONUtil.toList(JSONUtil.parseArray(content.toString()), MapContentInfo.class);
            for (MapContentInfo vo : list) {
                switch (vo.getMark()) {
                    case "shelfOrientation":
                        point.setShelfAngle(Double.parseDouble(String.valueOf(vo.getValue())));
                        break;
                    case "liftHeight":
                        point.setLiftHeight(Double.parseDouble(String.valueOf(vo.getValue())));
                        break;
                    case "isKeyPoint":
                        point.setKeyPoint(Integer.parseInt(String.valueOf(vo.getValue())));
                        break;
                    case "device_type_list":
                        point.setDeviceTypeList(String.valueOf(vo.getValue()));
                        break;
                    default:
                }
            }
        }
    }
}
